#include "ECGAcore.hpp"


ECGAcore::ECGAcore(Validator *val,GAmodSettings &settings) throw(ECGAcoreException):
GAcore(val,settings)
{
pr = new parameter();
pr->seed=0.25;
// length of chromosome: 4*8*32 DO NOT CHANGE!!! it's not everywhere a parameter.
pr->lchrom=1024;
//pop size. define by configuration file.
pr->popsize=200;
pr->pcross=1;
pr->tournament_size=45;
//ECGA allows also to define an other stopping parameter but we do not need because we have allready the CLC controller 
pr->stop_criteria=60;
pr->stop_criteria_arg=0; //allele convergence 
//to create the model
pr->learn_MPM=true; 
// theorethically useless variables...
pr->report_pop=false;
pr->report_string=false;
pr->report_fitness=false;
pr->report_MPM=false;
//load the sttings from the .cnf file
this->loadSettings(settings);
//initializing the ECGA random number generator
rnd = new randomG();
rnd->randomize( pr->seed );
//creating the Core.
ECGA= new ecga(pr,rnd,val);
}

ECGAcore::~ECGAcore()
{

}


int ECGAcore::loadSettings(GAmodSettings &settings,load_exc le) throw(ECGAcoreException)
{

TemplateGAmodObjWrapper<string> *strsett;
const char *tmp;


strsett=(TemplateGAmodObjWrapper<string>*)settings.get_setting("seed");
tmp= (strsett) ? strsett->value.c_str() : NULL;
if(tmp)
	{
	pr->seed=atof(tmp);
	IF_DBG_INFO(printf("[INFO] ECGACore::loadSettings: seed (%f)\n",pr->seed);)
	}
strsett=(TemplateGAmodObjWrapper<string>*)settings.get_setting("pop_size");
tmp= (strsett) ? strsett->value.c_str() : NULL;
if(tmp)
	{
	pr->popsize=atoi(tmp);
	IF_DBG_INFO(printf("[INFO] ECGACore::loadSettings: population size %d \n",pr->popsize);)
	}
	
strsett=(TemplateGAmodObjWrapper<string>*)settings.get_setting("tournament_size");
tmp= (strsett) ? strsett->value.c_str() : NULL;
if(tmp)
	{
	pr->tournament_size=atoi(tmp);
	IF_DBG_INFO(printf("[INFO] ECGACore::loadSettings: tournament size %d \n",pr->tournament_size);)
	}
	
strsett=(TemplateGAmodObjWrapper<string>*)settings.get_setting("pc");
tmp= (strsett) ? strsett->value.c_str() : NULL;
if(tmp)
	{
	pr->pcross=atof(tmp);
	IF_DBG_INFO(printf("[INFO] ECGACore::loadSettings: crossover probability %f \n",pr->pcross);)
	}
return 0;


}

int ECGAcore::getGenerationData(GAmodSettings &settings,HERAuint32 lista)
{

int np=0;
float a;
settings.clear();
GAmodObjWrapper *objval;
if(lista==0) lista = ~lista;

if(lista & ECGAcore::PARAM_BEST_SCORE)
    {
        Individuo b;
        b = M->getBestIndividuo();
        //sprintf(str,"%d",b.fitness);
        objval = new GAmodFloatSetting((float)b.fitness);
        settings.add_setting("best_score",objval);
        np++;
    }
    if(lista & ECGAcore::PARAM_MEAN_SCORE || lista & ECGAcore::PARAM_VAR_SCORE)
    {
        //sprintf(str,"%.4f",M->mean_fitness(&a));
        objval = new GAmodFloatSetting(M->mean_fitness(&a));
        settings.add_setting("mean_score",objval);
        //sprintf(str,"%.4f",a);
        objval = new GAmodFloatSetting(a);
        settings.add_setting("var_score",objval);
        np++;
    }

    if(lista & ECGAcore::PARAM_HAM_BEST)
    {
        //sprintf(str,"%.4f",this->M->hamming_distance(Popolazione::HAMMING_TYPE_BESTMED));
        objval = new GAmodFloatSetting(this->M->hamming_distance(Popolazione::HAMMING_TYPE_BESTMED));
        settings.add_setting("ham_best",objval);
        np++;
    }
return np;

}

int ECGAcore::runGeneration(int num)
{
// run for at most num generations
M=ECGA->run(this->myValidator,num);
//the returned value is an upper-bound, to have a precide number run the core with num=1.
return num;
}




